package com.crm.im.core.websocket;

import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.socket.CloseStatus;
import org.springframework.web.socket.TextMessage;
import org.springframework.web.socket.WebSocketSession;
import org.springframework.web.socket.handler.TextWebSocketHandler;

import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;
import com.crm.im.core.model.Message;
import com.crm.sys.push.DefaultMessagePusher;
import com.crm.user.model.UserAccount;
import com.crm.util.StringUtil;

 
public class SpringWebSocketHandler extends TextWebSocketHandler {
	
	@Autowired
	private DefaultMessagePusher messagePusher;
	
    private static final Map<Long,WebSocketSession> users;//这个会出现性能问题，最好用Map来存储，key用userid
    private static Logger logger = Logger.getLogger(SpringWebSocketHandler.class);
    private static final 	Gson gson =  new Gson();
    static {
        users = new HashMap<Long,WebSocketSession>();
    }
    
    public SpringWebSocketHandler() {
        // TODO Auto-generated constructor stub
    }

    /**
     * 连接成功时候，会触发页面上onopen方法
     */
    public void afterConnectionEstablished(WebSocketSession session) throws Exception {
        // TODO Auto-generated method stub
        System.out.println("connect to the websocket success......当前数量:"+users.size());
        //检测已经登录的链接并关闭
        closeLoginUser(session);
        
        UserAccount loginu = (UserAccount) session.getAttributes().get("WEBSOCKET_USER");
        users.put(loginu.getId(),session);
        //这块会实现自己业务，比如，当用户登录后，会把离线消息推送给用户
        //TextMessage returnMessage = new TextMessage("你将收到的离线");
        //session.sendMessage(returnMessage);
    }
    /**
     * 关闭同一登录用户 保存最新用户
     */
    private void closeLoginUser(WebSocketSession session){
    	 
    	try{
    		UserAccount loginu = (UserAccount) session.getAttributes().get("WEBSOCKET_USER");
            if(loginu!=null){ 
	           	 WebSocketSession user  =   users.get(loginu.getId());
	           	  if(user!=null){
   	                  UserAccount u = (UserAccount)user.getAttributes().get("WEBSOCKET_USER");
   	                  if (u!=null&&u.getId().equals(loginu.getId())) {
   	                      try {
   	                          if (user.isOpen()) {
   	                        	  Map<String, String> map = new HashMap<String, String>();
   	                       	      map.put("user", u.getId().toString());
   	                       	      map.put("file", u.getInfo().getPhoto());
   	                       	      map.put("type","3");
   	                       	      map.put("username", u.getInfo().getName());
   	                       	      map.put("content", "已在其它手机端登录，如非本人，请及时修改密码！");
   	                       	      user.sendMessage(new TextMessage( gson.toJson(map)));
   	                       	      user.close();
   	                         }
   	                      } catch (Exception e) {
   	                          e.printStackTrace();
   	                      }
   	                  }
	           	  }
            }
    	}catch(Exception e){
    		e.printStackTrace();
    	}
    	
    }
    
    /**
     * 关闭连接时触发
     */
    public void afterConnectionClosed(WebSocketSession session, CloseStatus closeStatus) throws Exception {
        logger.debug("websocket connection closed......");
        UserAccount u = (UserAccount) session.getAttributes().get("WEBSOCKET_USER");
        if(u!=null){
        	   System.out.println("用户"+u.getAccount()+"已退出！");
               users.remove(session);
               System.out.println("剩余在线用户"+users.size());
        }
     
    }

    /**
     * js调用websocket.send时候，会调用该方法
     */
    @Override    
    protected void handleTextMessage(WebSocketSession session, TextMessage message) throws Exception {
    	UserAccount u = (UserAccount)session.getAttributes().get("WEBSOCKET_USER");
    	if(u!=null){
    		try{
    		  Map<String, String> map = new HashMap<String, String>();
    		  //String myJson=   gson.toJson(message.getPayload());
       	      map = gson.fromJson(message.getPayload(), new TypeToken<Map<String, String>>() { }.getType());
       	      map.put("user", u.getId().toString());
       	      map.put("file", u.getInfo().getPhoto());
       	      map.put("username", u.getInfo().getName());
       	      sendMessageToUser(Long.parseLong(map.get("receiver")),new TextMessage( gson.toJson(map))); 
       	       try{
       	    	    Message nmessage =new Message();
	 	       	    nmessage.setMid(StringUtil.getUUID());
	 	       	    nmessage.setType("1");
	 	         	nmessage.setContent(map.get("content"));
	 				nmessage.setReceiver(map.get("receiver"));
	 				nmessage.setSender(map.get("user")+"|"+map.get("username"));
	 				nmessage.setFile(map.get("file")); 
        	        messagePusher.pushByWebSocket(nmessage);
       	       }catch(Exception e){
       	    	   
       	       }
       	       
    		}catch(Exception e){
    			e.printStackTrace();
    		}
    	}
        super.handleTextMessage(session, message);
    }

    public void handleTransportError(WebSocketSession session, Throwable exception) throws Exception {
        if(session.isOpen()){session.close();}
        logger.debug("websocket connection closed......");
        users.remove(session);
    }

    public boolean supportsPartialMessages() {
        return false;
    }
    
    /**
     * 取得所有在线用户
     * @return
     */
    public List<WebSocketSession> queryAll() {
   	    List<WebSocketSession> list = new ArrayList<WebSocketSession>();
        list.addAll(users.values());
        return list;
    }
    /**
     * 取得单个用户
     * @param uid
     * @return
     */
    public WebSocketSession get(Long uid) {
        return users.get(uid);
     } 
    
    /**
     * 给某个用户发送消息
     *
     * @param userName
     * @param message
     */
    public void sendMessageToUser(Long  userId, TextMessage message) {
    		WebSocketSession  user = users.get(userId);
    		if(user!=null&&user.isOpen()){
    			  try {
                     user.sendMessage(message);
                  } catch (Exception e) {
                      e.printStackTrace();
                  }
    		} 
    }
    
    /**
     * 给所有在线用户发送消息
     *
     * @param message
     */
    public void sendMessageToUsers(TextMessage message) {
    	for (Map.Entry<Long,WebSocketSession> entry : users.entrySet()) {
    		WebSocketSession  user = entry.getValue();
            try {
                if (user.isOpen()) {
                    user.sendMessage(message);
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

}